package org.example.rubbish.service.impl;

import jakarta.servlet.http.HttpServletRequest;
import org.example.rubbish.common.PageResult;
import org.example.rubbish.entity.AdminUser;
import org.example.rubbish.mapper.AdminUserMapper;
import org.example.rubbish.service.AdminUserService;
import org.example.rubbish.util.JwtUtils;
import org.example.rubbish.vo.AdminLoginResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class AdminUserServiceImpl implements AdminUserService {

    private static final Logger logger = LoggerFactory.getLogger(AdminUserServiceImpl.class);

    private final AdminUserMapper adminUserMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtils jwtUtils;

    @Autowired
    public AdminUserServiceImpl(AdminUserMapper adminUserMapper,
                                PasswordEncoder passwordEncoder,
                                JwtUtils jwtUtils) {
        this.adminUserMapper = adminUserMapper;
        this.passwordEncoder = passwordEncoder;
        this.jwtUtils = jwtUtils;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<AdminUser> adminUserOpt = adminUserMapper.selectByUsername(username);
        if (adminUserOpt.isEmpty()) {
            logger.warn("用户不存在: {}", username);
            throw new UsernameNotFoundException("用户不存在");
        }

        AdminUser adminUser = adminUserOpt.get();
        return User.builder()
                .username(adminUser.getUsername())
                .password(adminUser.getPassword())
                .roles(adminUser.getRole())
                .disabled(adminUser.getStatus() != null && adminUser.getStatus() == 0)
                .build();
    }


    @Override
    @Transactional
    public AdminLoginResult login(String username, String password, HttpServletRequest request) {
        if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
            throw new IllegalArgumentException("用户名和密码不能为空");
        }

        Optional<AdminUser> adminUserOpt = adminUserMapper.selectByUsername(username);
        if (adminUserOpt.isEmpty()) {
            logger.warn("管理员账号不存在: {}", username);
            throw new RuntimeException("管理员账号不存在");
        }

        AdminUser adminUser = adminUserOpt.get();
        // 查看数据库中的加密密码
        System.out.println("数据库中的密码: " + adminUser.getPassword());

        String pwd = passwordEncoder.encode(password);
        System.out.println(pwd);
        // 这里是最关键的地方 - 查看密码匹配结果

        boolean matches = passwordEncoder.matches(password, adminUser.getPassword());
        System.out.println("密码匹配结果: " + matches);

        if (!passwordEncoder.matches(password, adminUser.getPassword())) {
            logger.warn("密码错误: {}", username);
            throw new RuntimeException("密码错误");
        }

        if (adminUser.getStatus() != null && adminUser.getStatus() == 0) {
            logger.warn("管理员账号已被禁用: {}", username);
            throw new RuntimeException("管理员账号已被禁用");
        }

        String token = jwtUtils.generateToken(
                adminUser.getUsername(),
                adminUser.getId(),
                adminUser.getRole() != null ? adminUser.getRole() : "admin"
        );

        String clientIp = getClientIp(request);
        Date loginTime = new Date();
        adminUserMapper.updateLoginInfo(adminUser.getId(), clientIp, loginTime);

        AdminLoginResult result = new AdminLoginResult();
        result.setToken(token);
        result.setAdminUser(adminUser);
        result.setLoginTime(loginTime);
        result.setLoginIp(clientIp);

        logger.info("管理员登录成功: {}", username);
        return result;
    }

    @Override
    @Transactional
    public AdminUser createAdminUser(AdminUser adminUser) {
        if (adminUser == null) {
            throw new IllegalArgumentException("管理员信息不能为空");
        }

        if (!StringUtils.hasText(adminUser.getUsername()) || !StringUtils.hasText(adminUser.getPassword())) {
            throw new IllegalArgumentException("用户名和密码不能为空");
        }

        Optional<AdminUser> existingUser = adminUserMapper.selectByUsername(adminUser.getUsername());
        if (existingUser.isPresent()) {
            throw new RuntimeException("管理员用户名已存在");
        }

        // 设置默认值
        if (adminUser.getStatus() == null) adminUser.setStatus(1);
        if (adminUser.getRole() == null) adminUser.setRole("admin");
        Date now = new Date();
        if (adminUser.getCreateTime() == null) adminUser.setCreateTime(now);
        adminUser.setUpdateTime(now);

        // 加密密码
        adminUser.setPassword(passwordEncoder.encode(adminUser.getPassword()));

        int result = adminUserMapper.insert(adminUser);
        if (result <= 0) {
            throw new RuntimeException("创建管理员失败");
        }

        logger.info("创建管理员用户成功: {}", adminUser.getUsername());
        return adminUser;
    }

    @Override
    public PageResult<AdminUser> getAdminsWithPagination(Integer page, Integer size, String keyword) {
        if (page == null || page < 1) page = 1;
        if (size == null || size < 1) size = 10;

        // 获取所有数据（这里可以优化为直接查询分页数据，但基于你现有的 getAllAdmins 方法）
        List<AdminUser> allAdmins = adminUserMapper.selectAll();

        // 如果有搜索关键词，进行过滤
        if (keyword != null && !keyword.trim().isEmpty()) {
            String lowerKeyword = keyword.toLowerCase();
            allAdmins = allAdmins.stream()
                    .filter(admin ->
                            (admin.getUsername() != null && admin.getUsername().toLowerCase().contains(lowerKeyword)) ||
                                    (admin.getRealName() != null && admin.getRealName().toLowerCase().contains(lowerKeyword)) ||
                                    (admin.getDepartment() != null && admin.getDepartment().toLowerCase().contains(lowerKeyword))
                    )
                    .collect(Collectors.toList());
        }

        // 计算分页参数
        long total = allAdmins.size();
        int startIndex = (page - 1) * size;
        int endIndex = Math.min(startIndex + size, allAdmins.size());

        // 手动分页
        List<AdminUser> pageRecords = allAdmins.subList(startIndex, endIndex);

        return new PageResult<>(page, size, total, pageRecords);
    }
    @Override
    public AdminUser getAdminById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("ID不能为空");
        }
        return adminUserMapper.selectById(id)
                .orElseThrow(() -> new RuntimeException("管理员不存在"));
    }

    @Override
    public AdminUser getAdminByUsername(String username) {
        if (!StringUtils.hasText(username)) {
            throw new IllegalArgumentException("用户名不能为空");
        }
        return adminUserMapper.selectByUsername(username)
                .orElseThrow(() -> new RuntimeException("管理员不存在"));
    }

    @Override
    @Transactional
    public void softDeleteAdmin(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("ID不能为空");
        }

        int result = adminUserMapper.softDeleteById(id, new Date());
        if (result <= 0) {
            throw new RuntimeException("删除管理员失败");
        }
        logger.info("软删除管理员成功: {}", id);
    }

    @Override
    @Transactional
    public void updateStatus(Long id, Integer status) {
        if (id == null || status == null) {
            throw new IllegalArgumentException("ID和状态不能为空");
        }

        if (status != 0 && status != 1) {
            throw new IllegalArgumentException("状态值无效");
        }

        int result = adminUserMapper.updateStatus(id, status, new Date());
        if (result <= 0) {
            throw new RuntimeException("更新状态失败");
        }
        logger.info("更新管理员状态成功: ID={}, Status={}", id, status);
    }

    @Override
    @Transactional
    public AdminUser updateAdminUser(AdminUser adminUser) {
        if (adminUser == null || adminUser.getId() == null) {
            throw new IllegalArgumentException("管理员信息不完整");
        }

        // 检查用户名是否已被其他用户使用
        int count = adminUserMapper.countByUsernameExcludingId(adminUser.getUsername(), adminUser.getId());
        if (count > 0) {
            throw new RuntimeException("管理员用户名已存在");
        }

        adminUser.setUpdateTime(new Date());
        int result = adminUserMapper.update(adminUser);
        if (result <= 0) {
            throw new RuntimeException("更新管理员信息失败");
        }

        logger.info("更新管理员信息成功: {}", adminUser.getUsername());
        return getAdminById(adminUser.getId());
    }

    @Override
    @Transactional
    public void changePassword(Long id, String newPassword) {
        if (id == null || !StringUtils.hasText(newPassword)) {
            throw new IllegalArgumentException("ID和新密码不能为空");
        }

        if (newPassword.length() < 6) {
            throw new IllegalArgumentException("密码长度不能少于6位");
        }

        String encodedPassword = passwordEncoder.encode(newPassword);
        int result = adminUserMapper.updatePassword(id, encodedPassword, new Date());
        if (result <= 0) {
            throw new RuntimeException("修改密码失败");
        }
        logger.info("修改密码成功: {}", id);
    }

    @Override
    public boolean verifyCurrentPassword(Long id, String currentPassword) {
        if (id == null || !StringUtils.hasText(currentPassword)) {
            return false;
        }

        Optional<AdminUser> adminUserOpt = adminUserMapper.selectById(id);
        if (adminUserOpt.isEmpty()) {
            return false;
        }

        AdminUser adminUser = adminUserOpt.get();
        return passwordEncoder.matches(currentPassword, adminUser.getPassword());
    }



    @Override
    public boolean hasPermission(Long adminId, String permission) {
        if (adminId == null || !StringUtils.hasText(permission)) {
            return false;
        }

        Optional<AdminUser> adminUserOpt = adminUserMapper.selectById(adminId);
        if (adminUserOpt.isEmpty()) return false;

        AdminUser adminUser = adminUserOpt.get();
        if ("super_admin".equals(adminUser.getRole())) return true;

        return adminUser.getPermissions() != null &&
                adminUser.getPermissions().contains(permission);
    }

    private String getClientIp(HttpServletRequest request) {
        String[] headers = {"X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};

        for (String header : headers) {
            String ip = request.getHeader(header);
            if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
                return ip.split(",")[0].trim();
            }
        }

        return request.getRemoteAddr();
    }
}